package com.imist.nettybasic3.client;

import com.imist.nettybasic3.protocol.PacketCodeC;
import com.imist.nettybasic3.protocol.request.MessageRequestPacket;
import com.imist.nettybasic3.utils.LoginUtils;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.util.Date;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

public class NettyClient {
    private static final int MAX_RETRY = 5;
    private static final String HOST = "127.0.0.1";
    private static final int PORT = 8002;
    public static void main(String[] args) {
        Bootstrap bootstrap = new Bootstrap();
        NioEventLoopGroup workGroup = new NioEventLoopGroup();
        bootstrap.group(workGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS,5000)
                .option(ChannelOption.SO_KEEPALIVE,true)
                .option(ChannelOption.TCP_NODELAY,true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(new ClientHandler());
                    }
                });

        connect(bootstrap,HOST,PORT,MAX_RETRY);
    }

    private static void connect(Bootstrap bootstrap, String host, int port, int retry) {
        bootstrap.connect(host,port).addListener(future -> {
            if (future.isSuccess()){
                System.out.println(new Date() +" : 连接成功");
                //通过future拿到连接对象
                Channel channel = ((ChannelFuture)future).channel();
                //连接成功之后启动控制台线程
                startConsoleThread(channel);
            }else if (retry == 0){
                System.out.println(new Date() +" : 重连次数已用完，放弃连接");
            }else {
                //第几次重连
                int order =(MAX_RETRY - retry) + 1;
                // 本次重连的间隔
                int delay = 1 << order;
                System.out.println(new Date() + ":重连失败，第" +order+"次重连");
                bootstrap.config().group().schedule(() -> connect(bootstrap,host,port,retry -1),delay, TimeUnit.SECONDS);
            }
        });
    }

    private static void startConsoleThread(Channel channel) {
        new Thread(() ->{
            while (!Thread.interrupted()){
                if (LoginUtils.hasLogin(channel)){
                    System.out.println("输入消息发送至服务端:");
                    Scanner scanner = new Scanner(System.in);
                    String line = scanner.nextLine();
                    MessageRequestPacket messageRequestPacket = new MessageRequestPacket();
                    messageRequestPacket.setMessage(line);
                    ByteBuf byteBuf = PacketCodeC.INSTANCE.encode(channel.alloc(),messageRequestPacket);
                    channel.writeAndFlush(byteBuf);
                }
            }
        }).start();
    }


}
